// 数据类型：分为基本数据类型和引用数据类型
// 1.基本数据类型：Number、String、Boolean、Null、Udefined、Symbol、BigInt。
// ts定义的语法：   声明关键字 变量名:型 = 数值；
// 引用数据类型语法定义

// 内置类型
let a: Object = {};
let b: Array<number> = [1,2,3];
let c: Function = function(){};
let d: Date = new Date();
let e: RegExp = /hello/;

// 自定义类型
// 类型别名
type OrderId = number;

// 如果有的数据我既需要是number,还需要是string,还需要是bigint
// 联合类型
type OrderId1 = number | string | bigint;

// 在定义之初就不知道它的基本形态是什么样子的，只有在用的时候才知道的这种类型，可以先用泛型来定义
// 当hobby这里我不知道它是什么类型的时候，我就设置它为泛型
type Person<T> = {
   name:String,
   age:Number,
   info:T
}

// 在使用的时候传的值会被替换到那里
const xiaoming: Person<{hobby: Array<Number>}> = {
    name:"小明",
    age:20,
    info:{
        hobby:[1,2,3]
    }
}

// 并不是每次使用的时候都知道他的类型，此时可以使用extends
type Person1<T extends {hobby: String[]}> = {
   name:String,
   age:Number,
   info:T
}

// 此时使用person1这个类型时，这个泛型的数据类型中就必须要有hobby这个是属性
const xiaohua: Person1<{hobby:String[],aa:String}> = {
    name:"小花",
    age:20,
    info:{
        hobby:["2","3"],
        aa:"2"
    }
}

// 也可以直接赋值
type Person2<T = {hobby:Number[]}> = {
    name: Array<Number>,
    age: String[],
    info:T
}

const liming: Person2<{hobby: Number[]}> = {
    name:[1,2,3],
    age:["1","2","33"],
    info:{
        hobby: [2,3,5,7,9],
    }
}

// 我们需要对已有类型进行充分的利用
// 比如我现在有一个新的类型，只需要peoson中的name属性，不需要age属性，怎么办？不要重新定义，我们要对已有的类型进行充分的利用

// 用已有的类型来派生出来新的类型
// 此时有两种方法，要不一个一个往进取，
type Person4 = Pick<Person<{}>,"name">

// 获取对原有的一个一个删除来达到最终的效果
type Person5 = Omit<Person<{}>,"age">;